package com.sen.config;

import com.sen.security.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import javax.annotation.Resource;
import javax.sql.DataSource;

//AOP: 拦截器
//开启WebSecurity模式
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private UserService userService;

    @Autowired
    DataSource dataSource;

    //链式编程 授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //首页所有人都可以访问，功能页只对有权限的人才能访问
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");

        //没有权限默认会到登录页面,需要开启登录的页面
        //login
        http.formLogin().usernameParameter("username")
                .passwordParameter("password")
                .loginPage("/toLogin")
                .loginProcessingUrl("/login"); // 登陆表单提交请求;

        //注销,开启注销功能
        http.logout()
                .logoutSuccessUrl("/");//登录成功后跳转到首页
        //记住我
        http.rememberMe().rememberMeParameter("remember");
    }

    //权限认证，在springboot 2.1.x中可以直接使用
    //密码编码：PasswordEncoder
    //Spring security 5.0中新增了多种加密方式，也改变了密码的格式。
    //要想我们的项目还能够正常登陆，需要修改一下configure中的代码。我们要将前端传过来的密码进行某种方式加密
    //spring security 官方推荐的是使用bcrypt加密方式。
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //这些数据正常应该从数据库里面拿
        //在内存中拿，也可以在jdbc中拿，我们这里是用内存去拿
        //定义权限认证
        // auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
        //         .withUser("ergou").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
        //         .and()
        //         .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
        //         .and()
        //         .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
        auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
    }



}
